import { MenuUnfoldOutlined, MenuFoldOutlined } from '@ant-design/icons';
import { useQueryClient } from '@tanstack/react-query';
import { ConfigProvider, Menu, MenuProps } from 'antd';
import { m } from 'framer-motion';
import { useEffect, useMemo, useState } from 'react';
import { useLocation, useMatches, useNavigate } from 'react-router-dom';

import LogoImg from '@/assets/img/logo_m.png';
import MotionContainer from '@/components/animate/motion-container';
import { varSlide } from '@/components/animate/variants';
import Scrollbar from '@/components/Scrollbar';
import { useRouteToMenuFn, usePermissionRoutes, useFlattenedRoutes } from '@/router/hooks';
import { menuFilter } from '@/router/utils';
import { useSettingActions, useSettings } from '@/store/settingStore';
import userStore from '@/store/userStore';
import { useThemeToken } from '@/theme/hooks';

import { NAV_WIDTH } from './config';
import './nav.css';

import { ThemeLayout } from '#/enum';

const slideInLeft = varSlide({ distance: 10 }).inLeft;

type Props = {
  closeSideBarDrawer?: () => void;
};
export default function Nav(props: Props) {
  const queryClient = useQueryClient();
  const navigate = useNavigate();
  const matches = useMatches();
  const { pathname } = useLocation();

  const { colorPrimary, colorTextBase, colorBgElevated, colorBorder } = useThemeToken();

  const settings = useSettings();
  const { themeLayout } = settings;
  const { setSettings } = useSettingActions();

  const routeToMenuFn = useRouteToMenuFn();
  const permissionRoutes = usePermissionRoutes();
  const menuList = useMemo(() => {
    const menuRoutes = menuFilter(permissionRoutes);
    return routeToMenuFn(menuRoutes);
  }, [routeToMenuFn, permissionRoutes]);

  // 获取拍平后的路由菜单
  const flattenedRoutes = useFlattenedRoutes();

  /**
   * state
   */
  const [collapsed, setCollapsed] = useState(false);
  const [openKeys, setOpenKeys] = useState<string[]>([]);
  const [menuMode, setMenuMode] = useState<MenuProps['mode']>('inline');

  useEffect(() => {
    if (themeLayout === ThemeLayout.Vertical) {
      const openKeys = matches
        .filter((match) => match.pathname !== '/')
        .map((match) => match.pathname);
      setOpenKeys(openKeys);
    }
  }, [matches, themeLayout]);

  useEffect(() => {
    if (themeLayout === ThemeLayout.Vertical) {
      setCollapsed(false);
      setMenuMode('inline');
    }
    if (themeLayout === ThemeLayout.Mini) {
      setCollapsed(true);
      setMenuMode('inline');
    }
  }, [themeLayout]);

  /**
   * events
   */
  const onOpenChange: MenuProps['onOpenChange'] = (keys) => {
    setOpenKeys(keys);
  };
  const onClick: MenuProps['onClick'] = ({ key }) => {
    queryClient.clear();
    // 从扁平化的路由信息里面匹配当前点击的那个
    const nextLink = flattenedRoutes?.find((el) => el.key === key);

    // 处理菜单项中，外链的特殊情况
    // 点击外链时，不跳转路由，不在当前项目添加tab，不选中当前路由，新开一个 tab 打开外链
    if (nextLink?.hideTab && nextLink?.frameSrc) {
      window.open(nextLink?.frameSrc, '_blank');
      return;
    }

    navigate(key);
    props?.closeSideBarDrawer?.();
  };

  const setThemeLayout = (themeLayout: ThemeLayout) => {
    setSettings({
      ...settings,
      themeLayout,
    });
  };

  const toggleCollapsed = () => {
    if (!collapsed) {
      setThemeLayout(ThemeLayout.Mini);
    } else {
      setThemeLayout(ThemeLayout.Vertical);
    }
    setCollapsed(!collapsed);
  };

  const exit = () => {
    userStore.getState().actions.clearUserInfoAndToken();
    window.location.href = '/#/index';
  };

  return (
    <div
      className="flex h-full flex-col bg-[#F2F3F7]"
      style={{
        paddingLeft: 'calc(50vw - 712px)',
        width: `calc(50vw - 712px + ${NAV_WIDTH}px)`,
        // width: collapsed ? NAV_COLLAPSED_WIDTH : NAV_WIDTH,
        // borderRight: `1px dashed ${Color(colorBorder).alpha(0.6).toString()}`,
      }}
    >
      <div className="relative flex hidden h-20 items-center justify-center py-4">
        <MotionContainer className="flex items-center">
          <img src={LogoImg} className="h-[40px] w-[40px]" alt="LogoImg" />
          {themeLayout !== ThemeLayout.Mini && (
            <m.div variants={slideInLeft}>
              <span className="ml-2 text-xl font-bold" style={{ color: colorPrimary }}>
                Uniqtee会员中心
              </span>
            </m.div>
          )}
        </MotionContainer>
        <button
          onClick={toggleCollapsed}
          className="absolute right-0 top-7 z-50 hidden h-6 w-6 translate-x-1/2 cursor-pointer select-none rounded-full text-center !text-gray md:block"
          style={{ color: colorTextBase, borderColor: colorTextBase, fontSize: 16 }}
        >
          {collapsed ? <MenuUnfoldOutlined size={20} /> : <MenuFoldOutlined size={20} />}
        </button>
      </div>

      <Scrollbar
        style={{
          background: '#F2F3F7',
          height: 'calc(100vh - 177px)',
        }}
      >
        {/* <!-- Sidebar Menu --> */}
        <ConfigProvider
          theme={{
            components: {
              Menu: {
                borderRadius: 8,
                fontSize: 24,
                itemBg: '#F2F3F7',
                itemColor: '#686B73',
                itemMarginBlock: 20,
                itemMarginInline: 20,
                itemHoverBg: 'transparent',
                itemHoverColor: '#FD7901',
                itemSelectedBg: '#FD790119',
              },
            },
          }}
        >
          <Menu
            mode={menuMode}
            items={menuList}
            inlineIndent={6}
            className="custom-menu-wrapper"
            defaultOpenKeys={openKeys}
            defaultSelectedKeys={[pathname]}
            selectedKeys={[pathname]}
            openKeys={openKeys}
            onOpenChange={onOpenChange}
            onClick={onClick}
            inlineCollapsed={collapsed}
          />
        </ConfigProvider>

        {Object.keys(userStore.getState().userToken).length ? (
          <div
            className="font-weight mt-[20px] h-[80px] cursor-pointer pl-[32px] text-[20px] text-[#686B73]"
            onClick={exit}
          >
            退出登录
          </div>
        ) : (
          ''
        )}
      </Scrollbar>
    </div>
  );
}
